package com.zhoulz.homework.chaptor02.node;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.log4j.Logger;

import com.zhoulz.homework.chaptor02.config.Config;

/**
 * 服务器入站handler
 * @author zhoulz
 *
 */
public class PacketServerChannelInboundHandler extends ChannelInboundHandlerAdapter {
	Logger log = Logger.getLogger(PacketServerChannelInboundHandler.class);
	/**
	 * 缓存接收到的文件个数
	 */
	private int capacity = 10;
	private List<ReceiveFile> receiveFiles = new ArrayList<ReceiveFile>(capacity);
	
	private FileOutputStream fos = null;
	private long receiveBytes = 0;
	private ReceiveFile receiveFile;
	@Override
	public void channelRead(
			ChannelHandlerContext ctx, Object msg)
			throws Exception {
		Packet packet = (Packet)msg;
//		System.out.println("in starting "+packet.getType() + ", "+packet.getLength());
		switch (packet.getType()) {
			case FILE_SEND_START:
				// 文件开始传输，格式：节点名,文件名,文件大小
				// 接受的数据，存放于nodeName命名的目录下
				String data = packet.getData().toString(Config.ENCODING);
				String[] datas = data.split(",");
				log.info(String.format("Re %s: %s[%s]", datas[0], datas[1], datas[2]));
				String dir = String.format("%s/%s/", Config.DATA_DIR, datas[0]);
				File dataDir = new File(dir);
				if(!dataDir.exists()){
					dataDir.mkdirs();
				}
				fos = new FileOutputStream(new File(dir.concat(datas[1])));
				
				receiveBytes = 0;
				// 记录最近十个接收的文件
				receiveFile = new ReceiveFile(datas[0], 
						datas[1], 
						Long.parseLong(datas[2]),
						Calendar.getInstance().getTime(),
						0);
				if(receiveFiles.size() == capacity){
					receiveFiles.remove(capacity - 1);
				}
				receiveFiles.add(receiveFile);
				break;
			case FILE_SEND_ING:
				// 文件传输中
				packet.getData().readBytes(fos, packet.getLength());
				receiveBytes += packet.getLength();
				receiveFile.setReceiveProcess(Math.round((float)receiveBytes/receiveFile.getFileLength()*100));
				break;
			case FILE_SEND_DONE:
				// 文件传输结束,关闭流
				fos.flush();
				fos.close();
				// 调用outbound
				ctx.writeAndFlush(msg);
				break;
			case NODE_SHUTDOWN:
				// 对端节点要关闭，停止发送文件
				String toNodeName = packet.getData().toString(Config.ENCODING);
//				System.out.println("node shutdown: "+ toNodeName);
				CmdHelper.stopSendFile(toNodeName);
				break;
			default:
				break;
		}
	}
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
			throws Exception {
		log.error("文件接收异常", cause);
		super.exceptionCaught(ctx, cause);
	}
	
	public List<ReceiveFile> getReceiveFiles() {
		return receiveFiles;
	}
	public void setReceiveFiles(List<ReceiveFile> receiveFiles) {
		this.receiveFiles = receiveFiles;
	}
}
